﻿using System;
using System.Windows.Forms;
using JsonEditor.Models;
using JsonEditor.Utils;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace JsonEditor
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private TreeNode ParseJson(string json, string parent = "")
        {
            var root = SerializeHelper.DeserializeObject<TreeModel>(json);
            TreeNode node = new TreeNode(root.name);
            node.Tag = root;

            if (parent != "")
                treeView1.Nodes.Add(node);

            foreach (var child in root.children)
            {
                TreeNode childNode = ParseJson(SerializeHelper.SerializeObject<TreeModel>(child), node.Text);
                if (!node.Nodes.Contains(childNode))
                    node.Nodes.Add(childNode);
            }

            return node;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string json = @"{
                  ""name"": ""Root"",
                  ""children"": [
                    {
                      ""name"": ""Child 1"",
                      ""children"": []
                    },
                    {
                      ""name"": ""Child 2"",
                      ""children"": [
                        {
                          ""name"": ""Grandchild 1"",
                          ""children"": []
                        },
                        {
                          ""name"": ""Grandchild 2"",
                          ""children"": []
                        }
                      ]
                    }
                  ]
                }";
            BindTreeView(json);
        }

        #region
        public void BindTreeView(string strJson)
        {
            treeView1.Nodes.Clear();//清空Node

            if (IsJOjbect(strJson))
            {
                JObject jo = (JObject)JsonConvert.DeserializeObject(strJson);
                foreach (var joitem in jo)
                {
                    TreeNode jotree;
                    if (joitem.Value.GetType() == typeof(JObject))
                    {
                        jotree = new TreeNode(joitem.Key);
                        AddTreeChildNode(ref jotree, joitem.Value.ToString());
                        treeView1.Nodes.Add(jotree);
                    }
                    else if (joitem.Value.GetType() == typeof(JArray))
                    {

                        if (IsVarArray(joitem.Value.ToString()))
                        {
                            jotree = new TreeNode(joitem.Key);
                            AddTreeChildNode(ref jotree, joitem.Value.ToString());
                            treeView1.Nodes.Add(jotree);
                        }
                        else
                        {
                            jotree = new TreeNode(joitem.Key + ":" + joitem.Value.ToString());
                            treeView1.Nodes.Add(jotree);
                        }

                    }
                    else if (joitem.Value.GetType() == typeof(JValue))
                    {
                        jotree = new TreeNode(joitem.Key + ":" + joitem.Value.ToString());
                        treeView1.Nodes.Add(jotree);
                    }
                    else
                    {
                        jotree = new TreeNode(joitem.Key + ":" + joitem.Value.ToString());
                        treeView1.Nodes.Add(jotree);
                    }
                }
            }
            if (IsJArray(strJson))
            {

                JArray ja = (JArray)JsonConvert.DeserializeObject(strJson);
                foreach (JObject items in ja)
                {
                    TreeNode tree = new TreeNode();
                    foreach (var jaitem in items)
                    {
                        TreeNode jatree;
                        if (jaitem.Value.GetType() == typeof(JObject))
                        {
                            jatree = new TreeNode(jaitem.Key);
                            AddTreeChildNode(ref jatree, jaitem.Value.ToString());
                            tree.Nodes.Add(jatree);

                        }
                        else if (jaitem.Value.GetType() == typeof(JArray))
                        {
                            if (IsVarArray(jaitem.Value.ToString()))
                            {
                                jatree = new TreeNode(jaitem.Key);
                                AddTreeChildNode(ref jatree, jaitem.Value.ToString());
                                tree.Nodes.Add(jatree);
                            }
                            else
                            {
                                jatree = new TreeNode(jaitem.Key + ":" + jaitem.Value.ToString());
                                tree.Nodes.Add(jatree);
                            }
                        }
                        else if (jaitem.Value.GetType() == typeof(JValue))
                        {
                            jatree = new TreeNode(jaitem.Key + ":" + jaitem.Value.ToString());
                            tree.Nodes.Add(jatree);
                        }
                        else
                        {
                            jatree = new TreeNode(jaitem.Key + ":" + jaitem.Value.ToString());
                            tree.Nodes.Add(jatree);
                        }
                    }
                    treeView1.Nodes.Add(tree);
                }
            }
            treeView1.ExpandAll();
        }

        public void AddTreeChildNode(ref TreeNode parantNode, string value)
        {
            if (IsJOjbect(value))
            {
                JObject jo = (JObject)JsonConvert.DeserializeObject(value);
                foreach (var joitem in jo)
                {
                    TreeNode jotree;
                    if (joitem.Value.GetType() == typeof(JObject))
                    {
                        jotree = new TreeNode(joitem.Key);
                        AddTreeChildNode(ref jotree, joitem.Value.ToString());
                        parantNode.Nodes.Add(jotree);
                    }
                    else if (joitem.Value.GetType() == typeof(JArray))
                    {
                        if (IsVarArray(joitem.Value.ToString()))
                        {
                            jotree = new TreeNode(joitem.Key);
                            AddTreeChildNode(ref jotree, joitem.Value.ToString());
                            parantNode.Nodes.Add(jotree);
                        }
                        else
                        {
                            jotree = new TreeNode(joitem.Key + ":" + joitem.Value.ToString());
                            parantNode.Nodes.Add(jotree);
                        }
                    }
                    else
                    {
                        jotree = new TreeNode(joitem.Key + ":" + joitem.Value.ToString());
                        parantNode.Nodes.Add(jotree);
                    }
                }
            }
            if (IsJArray(value))
            {

                JArray ja = (JArray)JsonConvert.DeserializeObject(value);
                foreach (JObject item in ja)
                {
                    TreeNode tree = new TreeNode();
                    parantNode.Nodes.Add(tree);
                    foreach (var jaitem in item)
                    {
                        TreeNode jatree;
                        if (jaitem.Value.GetType() == typeof(JObject))
                        {
                            jatree = new TreeNode(jaitem.Key);
                            AddTreeChildNode(ref jatree, jaitem.Value.ToString());
                            tree.Nodes.Add(jatree);

                        }
                        else if (jaitem.Value.GetType() == typeof(JArray))
                        {
                            jatree = new TreeNode(jaitem.Key);
                            AddTreeChildNode(ref jatree, jaitem.Value.ToString());
                            tree.Nodes.Add(jatree);
                        }
                        else
                        {
                            jatree = new TreeNode(jaitem.Key + ":" + jaitem.Value.ToString());
                            tree.Nodes.Add(jatree);
                        }
                    }
                }

            }

        }

        public bool IsJOjbect(string value)
        {
            try
            {
                JObject ja = JObject.Parse(value);
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public bool IsJArray(string value)
        {
            try
            {
                JArray ja = JArray.Parse(value);
                return true;

            }
            catch (Exception)
            {
                return false;
            }
        }

        public bool IsVarArray(string value)
        {
            try
            {
                bool a = true;
                JArray ja = JArray.Parse(value);
                foreach (var item in ja)
                {
                    if (item.GetType() != typeof(JObject))
                    {
                        a = false;
                        break;
                    }
                }
                return a;
            }
            catch (Exception)
            {
                return false;
            }
        }
        #endregion
    }
}
